package com.tplhk.security.domain.service;

import com.tplhk.security.domain.dto.UserAuthority;
import com.tplhk.security.domain.dto.UserLoginDetails;
import com.tplhk.security.domain.entity.Role;
import com.tplhk.security.domain.entity.User;
import com.tplhk.security.domain.entity.UserRole;
import com.tplhk.security.domain.respositry.RoleRepository;
import com.tplhk.security.domain.respositry.UserRepository;
import com.tplhk.security.domain.respositry.UserRoleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @ClassName : UserService
 * @Description : TODO
 * @Author : taiping
 * @Date: 2021/6/24 14:37
 **/
@Slf4j
@Service
public class UserService implements UserDetailsService {

    @Autowired
    UserRepository userRepository;

    @Autowired
    UserRoleRepository userRoleRepository;

    @Autowired
    RoleRepository roleRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (null == user) {
            return null;
        }
        // 账户未锁定
//        final boolean nonLocked = user.getRetryCount() < this.maxRetryTimes ? true : false;
//        final boolean userActive = UserStatusConstant.STATUS_ACTIVE.equals(user.getStatus()) ? true : false;
        final boolean nonLocked = true;
        final boolean userActive = true;
        Set<GrantedAuthority> authorities = new HashSet<>();
        if (nonLocked && userActive) {
            /**
             * 生产做法：
             * 1. 相关表：
             *    t_platform: 平台表,
             *    t_permission: 平台权限表,
             *    t_role: 平台角色权限表
             *    t_user: 用户表
             *    m_user_platform: 平台用户表
             *    m_user_role: 用户角色表
             *
             * 2. 前端传入平台码 ( platformCode_clientType ,比如 tranning_web )
             * 3. 根据 userId, platformCode 通过 t_role + m_user_role 得到所有权限标识 ( authority 字符串 )
             * 4. 之前的例子是根据 role 鉴权，本例是根据权限标识  authority 鉴权
             */
            List<UserRole> userRoleList = userRoleRepository.findAllByUserId(user.getUserId());
            List<Long> roleIdList = userRoleList.stream().map(UserRole::getRoleId).collect(Collectors.toList());
            List<Role> roleList = roleRepository.findAllByIdIn(roleIdList);

            roleList.stream()
                    .map(Role::getName)
                    .map(item -> UserAuthority.builder().authority(item).build())
                    .forEach(authorities::add);
        }


        return UserLoginDetails.builder()
                .userId(user.getUserId())
                .username(user.getUsername())
                .password(user.getPassword())
                .accountNonExpired(true)
                .accountNonLocked(true)
                .credentialsNonExpired(true)
                .enabled(true)
                .authorities(authorities)
                .build();
    }
}
